From a92f199d6b8d83e4779e884e49f9e516b3812669 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Tue, 4 Nov 2025 19:30:58 +0100 Subject: [PATCH] dhcpv6: potential bug fix for checking DHCPV6_OPT_STATUS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit follow-up to b65ff293a96924f9b19dff8855232bfb9054b976 The previous logic checked that the DHCPV6_OPT_STATUS was more than 2 bytes, which meant that it would only be evaluated if the options *also* contained a status message. We should handle this option being exactly 2 bytes, so that DHCPV6_OPT_STATUS lacking a status message are correctly handled. The relevant RFC section does not state that status message can be absent https://www.rfc-editor.org/rfc/rfc8415#section-21.13 but the status message field is variable length and sets no mandates on its size. This ensures differing interpretations of this portion are handled adequately. It's not uncommon that various options behave in this 'can be zero length' way, so let's handle this option similarly. Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcp6c/pull/113 Signed-off-by: Álvaro Fernández Rojas --- src/dhcpv6.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 9c424ff..6aed871 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -1626,13 +1626,13 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) bool update_state = true; dhcpv6_for_each_option(odata + sizeof(*prefix) - 4U, odata + olen, stype, slen, sdata) { - if (stype == DHCPV6_OPT_STATUS && slen > 2) { + if (stype == DHCPV6_OPT_STATUS && slen >= 2) { /* RFC 8415 §21.22 The status of any operations involving this IA Prefix option is indicated in a Status Code option (see Section 21.13) in the IAprefix-options field. */ - uint8_t *status_msg = &sdata[2]; - uint16_t msg_len = slen - 2; + uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; + uint16_t msg_len = (slen > 2) ? slen - 2 : 0; uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); if (code == DHCPV6_Success) @@ -1709,13 +1709,13 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) bool update_state = true; dhcpv6_for_each_option(odata + sizeof(*addr) - 4U, odata + olen, stype, slen, sdata) { - if (stype == DHCPV6_OPT_STATUS && slen > 2) { + if (stype == DHCPV6_OPT_STATUS && slen >= 2) { /* RFC 8415 §21.6 The status of any operations involving this IA Address is indicated in a Status Code option in the IAaddr-options field, as specified in Section 21.13. */ - uint8_t *status_msg = &sdata[2]; - uint16_t msg_len = slen - 2; + uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; + uint16_t msg_len = (slen > 2) ? slen - 2 : 0; uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); if (code == DHCPV6_Success) -- 2.30.2